<?php

namespace app\worker\controller;

use app\common\helper\FormatHelper;
use app\common\service\VoiceService;
use think\facade\Env;
use think\worker\Server;
use Workerman\Lib\Timer;

/**
 *  php think worker:server -d  守护进程方式执行
 *  文档：https://www.kancloud.cn/thinkphp/think-worker/722897#Workermanthinkworker_12
 *  文档：https://www.kancloud.cn/manual/thinkphp5_1/354134
 */
class EngineerVoice extends Server
{
    protected $socket = 'http://211.149.138.212:2802';
    //protected $socket = 'http://127.0.0.1:2800';

    protected $uidConnections = [];
    protected $count = 1;

    /**
     * 收到信息
     * @param $connection 链接
     * @param $data 客户端 socket 发送参数
     */
    public function onMessage($connection, $data)
    {
        // 给connection临时设置一个lastMessageTime属性，用来记录上次收到消息的时间
        $connection->lastMessageTime = time();

        //客户端 socket 发送参数
        //请求参数：{"users_id":39,"type":1,"voice_type":1}
        $result = json_decode($data, true);
        $connection->result = $result;

        // 判断当前客户端是否已经验证,即是否设置了uid
        var_dump($result);
        if (is_array($result) && !isset($this->uidConnections[$result['users_id']])) {
            // 没验证的话把第一个包当做uid（这里为了方便演示，没做真正的验证）
            $connection->uuid = $result['users_id'];
            $this->uidConnections[$result['users_id']] = $connection;
        }
    }

    /**
     * 当连接建立时触发的回调函数
     * @param $connection
     */
    public function onConnect($connection)
    {
        echo $connection->getRemoteIP(). "\r\n";
    }

    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public function onClose($connection)
    {
        // 连接断开时删除映射
        if(isset($connection->uuid)) {
            echo $connection->id . 'disconnect'. "\r\n";
            unset($this->uidConnections[$connection->uuid]);
        }

    }

    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
    {
        echo "error $code $msg". $connection->error_get_last(). "\r\n";
    }

    /**
     * 每个进程启动
     * @param $worker
     */
    public function onWorkerStart($worker)
    {
        // 进程启动后设置一个每秒运行一次的定时器
        Timer::add(1, function () use ($worker) {
            $time_now = time();
            foreach ($worker->connections as $connection) {
                // 有可能该connection还没收到过消息，则lastMessageTime设置为当前时间
                if (empty($connection->lastMessageTime)) {
                    $connection->lastMessageTime = $time_now;
                    continue;
                }
                // 上次通讯时间间隔大于心跳间隔，则认为客户端已经下线，关闭连接
                if ($time_now - $connection->lastMessageTime >= 55) {

                    echo "心跳超时关闭链接". "\r\n";
                    $connection->close();
                }

                $result = $connection->result;
                //处理业务逻辑
                $voice_data = \app\worker\service\VoiceService::getEngineerVoice($result['users_id']);
                if ($voice_data['code'] == FormatHelper::SUCCESS) {
                    $this->broadcast(json_encode($voice_data['data']));
                }else {
                    echo $worker->id.' : '. $voice_data['msg'] . "\r\n";
                    $this->broadcast(json_encode($voice_data['msg']));
                }
            }
        });
        echo $worker->id.' : onWorkerStart' . "\r\n";
    }

    /**
     * 向所有验证的用户推送数据
     * @param $message
     */
    public function broadcast ($message)
    {
        var_dump('端口：2800 时间：'.time(),array_column($this->uidConnections,'uuid'));
        echo "\r\n";
        foreach($this->uidConnections as $connection) {
            $connection->send($message);
        }
    }

    /**
     * 针对uid推送数据
     *
     * @param $uid
     * @param $message
     */
    function sendMessageByUid($uid, $message)
    {
        if(isset($this->uidConnections[$uid])) {
            $connection = $this->uidConnections[$uid];
            $connection->send($message);
        }
    }


}
